package rox.rest;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.Random;

import javax.jcr.Credentials;
import javax.jcr.NodeIterator;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.Node;

import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.rest.HTTPMethod;
import org.exoplatform.services.rest.OutputTransformer;
//import org.exoplatform.services.rest.QueryTemplate;
import org.exoplatform.services.rest.Response;
import org.exoplatform.services.rest.URIParam;
import org.exoplatform.services.rest.URITemplate;
//import org.exoplatform.services.rest.QueryParam;
import org.exoplatform.services.rest.container.ResourceContainer;
import org.exoplatform.services.rest.transformer.StringOutputTransformer;

@URITemplate("/account/")
@OutputTransformer(StringOutputTransformer.class)
public class Exx implements ResourceContainer {
	private final RepositoryService repositoryService;	
	private boolean checked;
	public Exx(RepositoryService res) {
		repositoryService = res;		
		checked = false;
	}
	public void init() {
		Session session = getSession();
		if (session == null) {
			System.out.println("session = null");			
		}
		else {
			try {
				if (!session.getRootNode().hasNode("accounts")) {
					session.getRootNode().addNode("accounts","nt:accounts");
					session.save();
					System.out.println("A root node has been created.");
				}									
			} catch(RepositoryException re) {
				re.printStackTrace();
				System.out.println("Cannot create a node");
			} finally {
				session.logout();			
			}
			checked = true;
		}
	}
	@URITemplate("/getAcc/")
	@HTTPMethod("GET")
	public Response getUsers() {
		if (!checked) {
			init();
		}
		Session session = getSession();
		StringBuffer sb = new StringBuffer("<accounts>\n");
		sb.append("<acc user='user' pass='pass' />\n");		
		try {
			Node myNode = session.getRootNode().getNode("accounts"); //node
			NodeIterator nodes = myNode.getNodes();
			while(nodes.hasNext()) {
				Node node = nodes.nextNode();
				//print node's name
				System.out.println(node.getName());
				//
				String accInfo = "";
				accInfo = "<acc uuid='" + node.getUUID() + "' user='"+node.getProperty("user").getString()+
				"' pass='"+node.getProperty("pass").getString()+"'";				
				if (node.hasProperty("session") && node.hasProperty("lastModified"))
				{
					accInfo += " session = '" + node.getProperty("session").getString() + "' " +
							"lastModified = '" + node.getProperty("lastModified").getString() +"'";
				}				
				accInfo += " /> \n";
				System.out.println(accInfo);				
				sb.append(accInfo);
			}
		} catch(Exception e) {
			e.printStackTrace();
		}		
		sb.append("</accounts>");
		session.logout();
		System.out.println(sb.toString());
		return Response.Builder.ok(sb.toString(), "text/plain").build();
	}
	@URITemplate("/addAcc/{user}/{pass}/")
	@HTTPMethod("GET")
	public Response addUser(@URIParam("user") final String user,
							@URIParam("pass") final String pass) {
		if (!checked) {
			System.out.println("exxx, init() truoc deeee.");
			init();
		}
		Session session = getSession();
		try {
			Node myNode = session.getRootNode().getNode("accounts");
			Node node = myNode.addNode(user+"."+pass,"nt:acc");			
			node.setProperty("user", user);
			node.setProperty("pass", pass);			
			session.save();
			String xmlData = "<action>" +
			"	<result>pass</result>" +
			"	<message>New user created</message>" +			
			"	<info>"+user+" | "+pass+"</info>" +
			"</action>";
			//write a file saving xmlData that has been created above
			String pathFile = "D:/ChinhRoX/eXOJCR-Flex/exo-tomcat/webapps/Exx/WEB-INF/";
			String fileData = readFile(new File(pathFile + "Log.txt"));
			writeFile(new File(pathFile + "UserLog.txt"), xmlData + "\n" + fileData);
			//
			return Response.Builder.ok(xmlData, "text/plain").build();
		} catch(Exception e) {
			e.printStackTrace();
			return Response.Builder.ok("<action><result>fail</result></action>","text/plain").build();
		} finally {
			session.logout();			
		}
	}	
	@URITemplate("/login/{usr}/{pwd}/")
	@HTTPMethod("GET")
	public Response usrLogin(@URIParam("usr") String usr,@URIParam("pwd") String pwd)
	{
		if (!checked) {
			System.out.println("exxx, init() truoc deeee.");
			init();
		}
		
		boolean isLogined = false;
		Session session = getSession();
		StringBuffer sb = new StringBuffer("<login>\n");		
		
		try
		{
			Node nodes=session.getRootNode().getNode("accounts");
			NodeIterator Inode=nodes.getNodes();
			String tmpUsr;
			String tmpPwd;
			String sessionKey;
			System.out.print("bat dau tim");
			while(Inode.hasNext() && !isLogined)
			{
				Node node=Inode.nextNode();
				tmpUsr=node.getProperty("user").getString();
				tmpPwd=node.getProperty("pass").getString();
				long current_Time=System.currentTimeMillis();
				System.out.print(tmpUsr + " " + tmpPwd + "|" + usr + " " + pwd);
				if(tmpUsr.equals(usr) && tmpPwd.equals(pwd))
				{
					System.out.print("tim thay");
					System.out.print(current_Time);
					isLogined=true;
					sb.append("<status>OK</status> \n");
					sb.append("<usrID>");
					sb.append(node.getUUID());
					sb.append("</usrID> \n");
					sb.append("<sessionKey>");
					sessionKey=createSessionKey();
					sb.append(sessionKey);
					sb.append("</sessionKey> \n");
					node.setProperty("session", sessionKey);
					node.setProperty("lastModified", current_Time);
					System.out.println(current_Time);
				}				
			}
			session.save();			
			session.logout();
			if(!isLogined)
			{
				System.out.print("ko tim thay");
				sb.append("<status>False</status> \n");
			}
			
			sb.append("</login>");
			return Response.Builder.ok(sb.toString(), "text/plain").build();				
		}
		catch(Exception e)
		{
			sb.append("-di cui");
			e.printStackTrace();
			return Response.Builder.ok(sb.toString(), "text/plain").build();			
		}
	}
	@URITemplate("/remove/{user}/")
	@HTTPMethod("GET")
	public Response remove(@URIParam("user") String user)
	{
		if (!checked) {
			System.out.println("exxx, init() truoc deeee.");
			init();
		}
		Boolean ok = false;
		StringBuffer sb = new StringBuffer("<status>\n");
		Session session = getSession();
		System.out.println("get session okiiii");
		try {
			Node myNode = session.getRootNode().getNode("accounts");
			NodeIterator nodes = myNode.getNodes();
			while (nodes.hasNext() && !ok) {
				Node node = nodes.nextNode();
				if (user.equals(node.getProperty("user").getString())) {
					node.remove();
					session.save();
					sb.append("xoa thanh cong");
					System.out.println("xoa thanh cong");
					ok = true;					
				}
			}
		}
		catch (Exception e)
		{
			
		}
		if (!ok) {
			sb.append("khong tim thay user: " + user);
			System.out.println("ex, eo tim thay user: " + user);
		}
		session.logout();
		sb.append("</status>");
		return Response.Builder.ok(sb.toString(),"text/plain").build();
	}
	@URITemplate("/getId/{sid}/")
	@HTTPMethod("GET")
	public Response getAcc(@URIParam("sid") String id)
	{
		StringBuffer sb=new StringBuffer("<accounts>\n");
		
		Session session=getSession();
		try
		{
			System.out.print("lay q");
			Node node=session.getNodeByUUID(id);
			
			sb.append("<account> \n");
			sb.append("<user>");
			sb.append(node.getProperty("user").getString());
			sb.append("</user> \n");
			sb.append("<pass>");
			sb.append(node.getProperty("pass").getString());
			sb.append("</pass> \n");
			sb.append("</account> \n");	
			
			NodeIterator nodes=node.getNodes();			
			while(nodes.hasNext())
			{
				Node node1=nodes.nextNode();
				sb.append("<account> \n");
				sb.append("<user>");
				sb.append(node1.getProperty("user").getString());
				sb.append("</user> \n");
				sb.append("<pass>");
				sb.append(node1.getProperty("pass").getString());
				sb.append("</pass> \n");
				sb.append("</account> \n");				
			}			
			System.out.print("lay q thanh cong");			
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return Response.Builder.ok(sb.toString(), "text/plain").build();
		}
		sb.append("</accounts>");
		return Response.Builder.ok(sb.toString(), "text/plain").build();
	}
	//create a session
	private String createSessionKey()
	{
		String strKey=new String();
		Random rand=new Random();
		int no;
		for(int i=0;i<16;i++)
		{
			no=rand.nextInt(9);
			strKey+=String.valueOf(no);
		}
		return strKey;
	}
	/**
	 * get Session
	 * @return
	 */
	public Session getSession() {
		Credentials credentials = new SimpleCredentials("root", "exo".toCharArray());
		try {
			Repository repository = repositoryService.getRepository("repository");
			Session session = repository.login(credentials, "system");
			System.out.println("A session has just been created!");
			return session;
		} catch(Exception e) {
			e.printStackTrace();			
			return null;
		}
	}
	
	/**
	 * 
	 * @param file
	 * @param data
	 */
	public void writeFile(File file, String data) {
		//write a file containing the data that have just been created above
		FileOutputStream fos; 
	    DataOutputStream dos;
	    fileValidate(file);
	    try {	      
	      fos = new FileOutputStream(file);
	      dos=new DataOutputStream(fos);
	      //dos.writeInt(2333);
	      dos.writeChars(data);  
	    } catch (IOException ioe) {
	      ioe.printStackTrace();
	    }
	}
	public String readFile(File file) {
	    //...checks on aFile are elided
	    StringBuilder contents = new StringBuilder();
	    fileValidate(file);
	    try {
	    	//use buffering, reading one line at a time
	    	//FileReader always assumes default encoding is OK!
	    	BufferedReader input =  new BufferedReader(new FileReader(file));
	    	try {
	    		String line = null; //not declared within while loop		        
		        while (( line = input.readLine()) != null){
		          contents.append(line);
		          //contents.append(System.getProperty("line.separator"));
		        }
	    	}
	    	finally {
	        input.close();
	    	}
	    } catch (IOException ex){
	      ex.printStackTrace();
	    }    
	    return contents.toString();
	}
	public void fileValidate(File aFile) {
		if (aFile == null) {
		      System.out.println("File should not be null.");
		}
		if (!aFile.exists()) {
			System.out.println("File does not exist: " + aFile);
		}
		if (!aFile.isFile()) {
			System.out.println("Should not be a directory: " + aFile);
		}
		if (!aFile.canWrite()) {
			System.out.println("File cannot be written: " + aFile);
		}
	}
}